home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / rsxwdk2s.zip / RSXWDK / LIBSRC / WIN / SELECTOR.C < prev    next >
C/C++ Source or Header  |  1995-01-05  |  4KB  |  229 lines

  1. #include <sys/rsxw32.h>
  2.  
  3. #ifdef __OPTIMIZE__
  4. #define INLINE static inline
  5. #else
  6. #define INLINE static
  7. #endif
  8.  
  9. #define CHECKERR "jnc    1f\n\tmovl   $-1, %0 \n\tjmp    2f \n\t1: \n\t"
  10. #define CHECKERR0 "jnc    1f\n\tmovl   $0, %0 \n\tjmp    2f \n\t1: \n\t"
  11. #define CHECK_ERR_DPMI10 "jc    2f\n\t"
  12. #define OKEAX0 "xorl   %0, %0 \n\t2: \n\t"
  13. #define END "2: \n\t"
  14.  
  15. /*
  16. **  DPMI functions
  17. */
  18.  
  19. /* return selector or null */
  20. INLINE int AllocLDT(int n_sel)
  21. {
  22.     register unsigned int _v;
  23.  
  24.     __asm__ __volatile__(
  25.     "call   _dpmi31 \n\t"
  26.     CHECKERR0
  27.     "movzwl %%ax, %0\n\t"
  28.     END
  29.     : "=a" (_v)
  30.     : "c" (n_sel) , "0" (0x000)
  31.     : "ax","cx" );
  32.     return _v ;
  33. }
  34.  
  35. INLINE int FreeLDT(int sel)
  36. {
  37.     register int _v;
  38.  
  39.     __asm__ __volatile__(
  40.     "call   _dpmi31 \n\t"
  41.     CHECKERR
  42.     OKEAX0
  43.     : "=a" (_v)
  44.     : "b" (sel) , "0" (0x001)
  45.     : "ax","bx" );
  46.  
  47.     return _v ;
  48. }
  49.  
  50. /* return base address or null */
  51. INLINE unsigned int GetBaseAddress(int sel)
  52. {
  53.     register unsigned int _v;
  54.  
  55.     __asm__ __volatile__(
  56.     "call   _dpmi31 \n\t"
  57.     CHECKERR0
  58.     "shll   $16, %%ecx  \n\t"
  59.     "movw   %%dx, %%cx \n\t"
  60.     "movl   %%ecx, %0 \n\t"
  61.     END
  62.     : "=a" (_v)
  63.     : "b" (sel) , "0" (0x006)
  64.     : "ax","bx","cx","dx" );
  65.  
  66.     return _v ;
  67. }
  68.  
  69. INLINE int SetBaseAddress(int sel, unsigned int base)
  70. {
  71.     register int _v;
  72.  
  73.     __asm__ __volatile__(
  74.     "call   _dpmi31 \n\t"
  75.     CHECKERR
  76.     OKEAX0
  77.     : "=a" (_v)
  78.     : "b" (sel),"c" ((unsigned short)(base>>16)),
  79.       "d" ((unsigned short)base),"0" (0x007)
  80.     : "ax","bx","cx","dx" );
  81.  
  82.     return _v ;
  83. }
  84.  
  85. INLINE int SetLimit(int sel, unsigned int limit)
  86. {
  87.     register int _v;
  88.  
  89.     __asm__ __volatile__(
  90.     "call   _dpmi31 \n\t"
  91.     CHECKERR
  92.     OKEAX0
  93.     : "=a" (_v)
  94.     : "b" (sel),"c" ((unsigned short)(limit>>16)),
  95.       "d" ((unsigned short)limit),"0" (0x008)
  96.     : "ax","bx","cx","dx" );
  97.  
  98.     return _v ;
  99. }
  100.  
  101. /*
  102. INLINE unsigned short get_data_seg(void)
  103. {
  104.     register unsigned short v;
  105.     __asm__("mov %%ds, %0 \n\t"
  106.         : "=r" ((unsigned short) v) );
  107.     return v;
  108. }
  109. */
  110.  
  111. /* these selectors are needed for thunking */
  112. #define N_SEL 5
  113. static int _sys_sel[N_SEL];
  114.  
  115.  
  116. /*
  117. **  init / free selectors
  118. */
  119.  
  120. static int init_selector(int * sel)
  121. {
  122.     if (!(*sel = AllocLDT(1)))
  123.     return -1;
  124.  
  125.     if (SetLimit(*sel, 0xFFFF)) {
  126.     FreeLDT(*sel);
  127.     return -1;
  128.     }
  129.     else
  130.     return 0;
  131. }
  132.  
  133. int _sys_init_selectors(void)
  134. {
  135.     int i;
  136.     int ret = 0;
  137.  
  138.     for (i=0; i<N_SEL; i++)
  139.     ret |= init_selector(_sys_sel + i);
  140.     return ret;
  141. }
  142.  
  143. static int free_selector(int sel)
  144. {
  145.     return FreeLDT(sel);
  146. }
  147.  
  148. int _sys_free_selectors(void)
  149. {
  150.     int i;
  151.     int ret = 0;
  152.  
  153.     for (i=0; i<N_SEL; i++)
  154.     ret |= free_selector(_sys_sel[i]);
  155.     return ret;
  156. }
  157.  
  158.  
  159. /*
  160.  *  program layout:
  161.  *   for each 64KB one selector with limit 0xFFFFF
  162.  *
  163.  *   0--------1--------2----------------------    n * 64 KB
  164.  *   |          | sel1,2 | sel3,4 |    ...     |
  165.  *   0----------------------------------------
  166.  *
  167.  */
  168.  
  169.  
  170. /*
  171.  *  convert selectors
  172.  */
  173.  
  174.  
  175. ULONG _rsx_32to16(void *pointer32)
  176. {
  177.     static int sel_index = 0;
  178.  
  179.     if (!pointer32)                    /* NULL Parameter */
  180.     return 0;
  181.     else if ((ULONG)pointer32 <= 0xFFFF)        /* MAKEINTRESOURCE */
  182.     return (ULONG) pointer32;
  183.     else if ((int)pointer32 <= _sys_last_addr) {    /* take sel from rsxw32 */
  184.     ULONG off = (int) pointer32;
  185.     ULONG sel;
  186.  
  187.     off -= 0x10000L;                /* sub empty region */
  188.     sel = _sys_first_sel + ((off >> 15) << 3);  /* index of sel * 8 */
  189.  
  190.     return ((sel << 16) | (off & 0x7FFF));
  191.     }
  192.  
  193.     sel_index ++ ;
  194.     if (sel_index >= N_SEL)
  195.     sel_index = 0;
  196.  
  197.     if (SetBaseAddress(_sys_sel[sel_index], (ULONG)pointer32 + _sys_base_addr))
  198.     return 0;
  199.     else
  200.     return _sys_sel[sel_index] << 16;
  201. }
  202.  
  203. void * _rsx_16to32(unsigned long farp)
  204. {
  205.     unsigned long linaddr;
  206.  
  207.     linaddr = GetBaseAddress(farp >> 16) + (farp & 0xFFFF);
  208.  
  209.     return (void *) (linaddr - _sys_base_addr);
  210. }
  211.  
  212. /*
  213. ** return 16bit stack
  214. ** convert value x to  sel : x & 0xFFFF
  215. */
  216. ULONG _rsx_stack16_sel(void *pointer32)
  217. {
  218.     ULONG off = (int) pointer32;
  219.     ULONG sel;
  220.  
  221.     off -= 0x10000L;
  222.     sel = _sys_first_sel + ((off >> 15) << 3);
  223.     off &= 0xFFFF;
  224.     if (off > 0x7FFF)
  225.     sel += 8;
  226.  
  227.     return (sel);
  228. }
  229.